package com.fingard.dsp.bank.directbank.hbb01;

import com.fingard.FGBiz;
import com.fingard.constant.Format;
import com.fingard.db.JDBCHelper;
import com.fingard.dsp.bank.directbank.PaymentState;
import com.fingard.dsp.bank.directbank.bankInterface.ISinglePay;
import com.fingard.dsp.bank.reqrespobj.single.*;
import com.fingard.dsp.bank.reqrespobj.single.detail.ReqPayRecDetail;
import com.fingard.dsp.bank.reqrespobj.single.detail.ReqQrySglBatPayDetail;
import com.fingard.dsp.bank.reqrespobj.single.detail.RetAtsSglDetail;
import com.fingard.net.ConnState;
import com.fingard.text.StringHelper;
import com.fingard.xml.XElement;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

import java.sql.Connection;
import java.util.Date;
import java.util.Map;
import java.util.UUID;

/**
 * @author Parker on 2019-08-14.
 * @version 1.0
 */
public class HBB01SinglePay extends HBB01Base implements ISinglePay {
    @Override
    public RetAtsSingle d_1908_SglPay(ReqSingle p_req1908) throws Exception {
        //返回ATS的对象
        RetAtsSingle retAts = new RetAtsSingle(p_req1908.reqHeader);
        Connection conn = FGBiz.getLocalDbConn();

        HBB01Header bankHeader = new HBB01Header();
        bankHeader.serialNo = p_req1908.reqHeader.transSeqID;
        if ("1".equals(p_req1908.singleDetail.sameBnk)) {//同行
            bankHeader.serviceId = "CBE020100";
        } else {
            bankHeader.serviceId = "CBE020102";
        }
        RetAtsSglDetail retDetail = new RetAtsSglDetail();
        XmlTextWriter xmlWriter = new XmlTextWriter();
        try {
            writeCommonHeader(xmlWriter, bankHeader);
            XElement tmpXElement = new XElement("body", "");
            tmpXElement.addChild(new XElement("payAccount", p_req1908.singleDetail.payAct));
            tmpXElement.addChild(new XElement("payAccountName", p_req1908.singleDetail.payName));
            tmpXElement.addChild(new XElement("recAccount", p_req1908.singleDetail.recAct));
            tmpXElement.addChild(new XElement("recAccountName", p_req1908.singleDetail.recName));
            tmpXElement.addChild(new XElement("payAmount", p_req1908.singleDetail.payAmount));
            tmpXElement.addChild(new XElement("currencyType", StringHelper.hasAnyChar(p_req1908.singleDetail.payCur) ? convertCurToBank(p_req1908.singleDetail.payCur) : "01"));
            tmpXElement.addChild(new XElement("payRem", p_req1908.singleDetail.purpose));//对账码
            tmpXElement.addChild(new XElement("pubPriFlag", "1".equals(p_req1908.singleDetail.isPrivate) ? "1" : "0"));

            if ("1".equals(p_req1908.singleDetail.sameBnk)) {//同行
                tmpXElement.addChild(new XElement("businessCode", "020100"));
            } else {
                tmpXElement.addChild(new XElement("businessCode", "020102"));
                tmpXElement.addChild(new XElement("recAccountOpenBank", p_req1908.singleDetail.recBankLocation));
                tmpXElement.addChild(new XElement("unionBankNo", p_req1908.singleDetail.cnapsCode));
                tmpXElement.addChild(new XElement("rmtType", "1".equals(p_req1908.singleDetail.paySpd) ? "1" : "0"));
                tmpXElement.addChild(new XElement("recBankType", "1"));
            }
            xmlWriter.writeXElement(tmpXElement);
            //写入签名数据
            xmlWriter.writeElementString("sign", getSingData(xmlWriter));
            xmlWriter.writeEndDocument();

            String[] retStrArr = sendToBank(xmlWriter.toXmlString());
            if (retStrArr[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(retStrArr[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String returnCode = tmpBkReader.getFirstText("/ebank/head/retCode");
                    String returnMsg = tmpBkReader.getFirstText("/ebank/head/retMessage");
                    retDetail.respCode = "0";
                    retDetail.respInfo = returnMsg;
                    retDetail.transAmt = p_req1908.singleDetail.payAmount;
                    retDetail.reqSeqID = p_req1908.singleDetail.askNumber;

                    if (returnCode != null && returnCode.equals("000000")) {
                        retDetail.transState = returnCode + "+" + tmpBkReader.getFirstText("/ebank/body/orderState");
                    } else {
                        retDetail.transState = returnCode;
                    }
                    retDetail.payInfoCode = retDetail.transState;

                } else {
                    retDetail.respCode = "-1";
                    retDetail.respInfo = tmpSbMsg.toString();
                }
                //记录ats支付流水号对应的银行指令流水号，供查询状态接口使用
                String uuid = UUID.randomUUID().toString().replaceAll("-", "");
                JDBCHelper.update(conn, INSERTSEQ, new Object[]{uuid, p_req1908.reqHeader.bankCode, Format.Date8Format.format(new Date()), p_req1908.singleDetail.askNumber, tmpBkReader.getFirstText("/ebank/head/orderFlowNo")});
            } else if (retStrArr[0].equals(ConnState.FAIL)) {
                retDetail.respCode = "0";
                retDetail.respInfo = retStrArr[1];
                retDetail.reqSeqID = p_req1908.singleDetail.askNumber;
                retDetail.transState = PaymentState.FAIL_Payment;
                retDetail.payInfoCode = retStrArr[0];
            } else {
                retDetail.respCode = "-1";
                retDetail.respInfo = retStrArr[1];
                retDetail.reqSeqID = p_req1908.singleDetail.askNumber;
            }
        } catch (Exception e) {
            retAts.writeRespCode("-1");
            retAts.writeRespInfo(e.getMessage());
        } finally {
            conn.close();
        }
        retAts.writeRetDetail(retDetail);
        return retAts;
    }

    @Override
    public RetAtsSingle d_1944_QrySglPay(ReqQrySingle p_req1944) throws Exception {
        RetAtsSingle retAts = new RetAtsSingle(p_req1944.reqHeader);
        RetAtsSglDetail retDetail = new RetAtsSglDetail();
        Connection conn = FGBiz.getLocalDbConn();
        try {
            HBB01Header bankHeader = new HBB01Header();
            bankHeader.serialNo = p_req1944.reqHeader.transSeqID;
            bankHeader.serviceId = "CBE020105";
            XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
            writeCommonHeader(xmlWriter, bankHeader);
            XElement tmpXElement = new XElement("body", "");
            tmpXElement.addChild(new XElement("searchPayAccount", p_req1944.payAct));
            tmpXElement.addChild(new XElement("searchRecAccount", p_req1944.recAct));
            tmpXElement.addChild(new XElement("beginDate", Format.Date8Format.format(Format.DateTimeFormat.parse(p_req1944.bgnDate))));
            tmpXElement.addChild(new XElement("endDate", Format.Date8Format.format(Format.DateTimeFormat.parse(p_req1944.bgnDate))));
            tmpXElement.addChild(new XElement("turnPageBeginPos", "1"));//翻页数据起始位置
            if ("1".equals(p_req1944.sameBnk)) {
                tmpXElement.addChild(new XElement("businessCode", "020100"));//
            } else {
                tmpXElement.addChild(new XElement("businessCode", "020102"));//
            }
            xmlWriter.writeXElement(tmpXElement);
            //写入签名数据
            xmlWriter.writeElementString("sign", getSingData(xmlWriter));
            xmlWriter.writeEndDocument();
            String[] tmpRetBkStr = sendToBank(xmlWriter.toXmlString());
            if (tmpRetBkStr[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpRetBkStr[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String returnCode = tmpBkReader.getFirstText("/ebank/head/retCode");
                    String returnMsg = tmpBkReader.getFirstText("/ebank/head/retMessage");
                    if (returnCode != null && returnCode.equals("000000")) {
                        Map<String, Object> selMap = JDBCHelper.execQuerySingle(conn, SELECTSEQ, new Object[]{p_req1944.askNumber, p_req1944.reqHeader.bankCode});
                        if (selMap.size() > 0) {
                            while (tmpBkReader.read("/ebank/body/list/row")) {
                                XElement readedXElement = tmpBkReader.readedXElement;
                                if (selMap.get("BANKREQSEQID").toString().equals(readedXElement.getSingleText("orderFlowNo"))) {
                                    retDetail.respCode = "0";
                                    retDetail.respInfo = returnMsg;
                                    retDetail.payInfoCode = returnCode + "+" + readedXElement.getSingleText("orderState");
                                    retDetail.transState = returnCode + "+" + readedXElement.getSingleText("orderState");
                                    retDetail.transAmt = readedXElement.getSingleText("payAmount");
                                    retDetail.reqSeqID = p_req1944.askNumber;
                                    break;
                                }
                            }
                        } else {
                            retDetail.respCode = "-1";
                            retDetail.respInfo = "交易流水号关联映射异常，请检查";
                        }
                    } else {
                        retDetail.respCode = "-1";
                        retDetail.respInfo = returnMsg;
                    }
                } else {
                    retDetail.respCode = "-1";
                    retDetail.respInfo = tmpSbMsg.toString();
                }
            } else {
                retDetail.respCode = "-1";
                retDetail.respInfo = tmpRetBkStr[1];
            }

        } catch (Exception e) {
            retDetail.respCode = "-1";
            retDetail.respInfo = e.getMessage();
            e.printStackTrace();
        } finally {
            conn.close();
        }
        retAts.writeRetDetail(retDetail);
        return retAts;
    }

    @Override
    public RetAtsSingleBat d_1908BAT_SglBatPay(ReqSingleBat p_req1908BAT) throws Exception {
        //返回ATS的对象
        RetAtsSingleBat retAts = new RetAtsSingleBat(p_req1908BAT);
        retAts.reqBatchNO = p_req1908BAT.reqBatchNO;
        retAts.batRespCode = "0";
        retAts.batTransState = "";
        retAts.batPayInfoCode = "";
        while (p_req1908BAT.readRecord()) {
            ReqPayRecDetail tmpDetail = p_req1908BAT.readedDetail;
            ReqSingle req1908 = new ReqSingle(p_req1908BAT.reqHeader);
            req1908.singleDetail = tmpDetail;
            RetAtsSingle eachRet = d_1908_SglPay(req1908);

            retAts.writeRetDetail(eachRet.retDetail);
        }
        retAts.writeAfterDetail();
        return retAts;
    }

    @Override
    public RetAtsSingleBat d_1944BAT_QrySglBatPay(ReqQrySingleBat p_req1944BAT) throws Exception {
        RetAtsSingleBat retAts = new RetAtsSingleBat(p_req1944BAT.reqHeader);
        retAts.reqBatchNO = p_req1944BAT.reqBatchNO;
        try {
            retAts.batRespCode = "0";
            while (p_req1944BAT.readRecord()) {
                ReqQrySglBatPayDetail tmpDetail = p_req1944BAT.readedDetail;
                ReqQrySingle req1944 = new ReqQrySingle(tmpDetail, p_req1944BAT.reqHeader);
                RetAtsSingle resp1944 = d_1944_QrySglPay(req1944);
                retAts.writeRetDetail(resp1944.retDetail);
            }
        } catch (Exception ex) {
            WriteBankLogLn(ex);
            retAts = new RetAtsSingleBat(p_req1944BAT.reqHeader);
            retAts.batRespCode = "-1";
            retAts.batRespInfo = ex.getMessage();
        }

        retAts.writeAfterDetail();
        return retAts;
    }
}
